<?php

/**
 * 图片处理类
 * 
 * @package    01CMS
 * @subpackage system
 * @author     rolong at vip.qq.com
 * @version    1.0.0
 * @link       http://www.01cms.com
 */

class ImageLib
{
    public $imageLibrary = 'gd2';
    public $libraryPath = '';
    public $dynamicOutput = FALSE;
    public $sourceImage = '';
    public $newImage = '';
    public $width = '';
    public $height = '';
    public $quality = '100';
    public $createThumb = FALSE;
    public $thumbMarker = '_thumb';
    public $fullThumbPath;
    public $thumbPadColor = '#ffffff';
    public $thumbWidth = '';
    public $thumbHeight = '';
    public $maintainRatio = TRUE;
    public $masterDim = 'auto';
    public $rotationAngle = '';
    public $xAxis = '';
    public $yAxis = '';
    
    public $wmText = '';
    public $wmType = 'text';
    public $wmXTransp = 4;
    public $wmYTransp = 4;
    public $wmOverlayPath = '';
    public $wmFontPath = '';
    public $wmFontSize = 17;
    public $wmVrtAlignment = 'B';
    public $wmHorAlignment = 'C';
    public $wmPadding = 5;
    public $wmHorOffset = 0;
    public $wmVrtOffset = 0;
    public $wmFontColor = '#ffffff';
    public $wmShadowColor = '';
    public $wmShadowDistance = 1;
    public $wmOpacity = 50;
    
    public $sourceFolder = '';
    public $destFolder = '';
    public $mimeType = '';
    public $origWidth = '';
    public $origHeight = '';
    public $imageType = '';
    public $sizeStr = '';
    public $fullSrcPath = '';
    public $fullDstPath = '';
    public $createFnc = 'imagecreatetruecolor';
    public $copyFnc = 'imagecopyresampled';
    public $errorMsg = '';
    public $wmUseDropShadow = FALSE;
    public $wmUseTruetype = FALSE;

    function clear ()
    {
        $props = array('sourceFolder', 'destFolder', 'sourceImage', 'fullSrcPath', 'fullDstPath', 'newImage', 'imageType', 'sizeStr', 'quality', 'origWidth', 'origHeight', 'rotationAngle', 'xAxis', 'yAxis', 'createFnc', 'copyFnc', 'wmOverlayPath', 'wmUseTruetype', 'dynamicOutput', 'wmFontSize', 'wmText', 'wmVrtAlignment', 'wmHorAlignment', 'wmPadding', 'wmHorOffset', 'wmVrtOffset', 'wmFontColor', 'wmUseDropShadow', 'wmShadowColor', 'wmShadowDistance', 'wmOpacity');
        
        foreach ($props as $val)
        {
            $this->$val = '';
        }
        
        $this->masterDim = 'auto';
    }

    function initialize ($props = array())
    {
        if (count($props) > 0)
        {
            foreach ($props as $key => $val)
            {
                $this->$key = $val;
            }
        }
        
        if ($this->sourceImage == '')
        {
            $this->setError('源图片不存在');
            return FALSE;
        }
        
        if (! function_exists('getimagesize'))
        {
            $this->setError('没有加载GD扩展');
            return FALSE;
        }
        
        $this->imageLibrary = strtolower($this->imageLibrary);
        
        if (function_exists('realpath') and @realpath($this->sourceImage) !== FALSE)
        {
            $fullSourcePath = str_replace("\\", "/", realpath($this->sourceImage));
        }
        else
        {
            $fullSourcePath = $this->sourceImage;
        }
        
        $x = explode('/', $fullSourcePath);
        $this->sourceImage = end($x);
        $this->sourceFolder = str_replace($this->sourceImage, '', $fullSourcePath);
        
        if (! $this->getImageProperties($this->sourceFolder . $this->sourceImage))
        {
            return FALSE;
        }
        
        if ($this->newImage == '')
        {
            $this->destImage = $this->sourceImage;
            $this->destFolder = $this->sourceFolder;
        }
        else
        {
            if (strpos($this->newImage, '/') === FALSE)
            {
                $this->destFolder = $this->sourceFolder;
                $this->destImage = $this->newImage;
            }
            else
            {
                if (function_exists('realpath') and @realpath($this->newImage) !== FALSE)
                {
                    $fullDestPath = str_replace("\\", "/", realpath($this->newImage));
                }
                else
                {
                    $fullDestPath = $this->newImage;
                }
                
                if (! preg_match("#\.(jpg|jpeg|gif|png)$#i", $fullDestPath))
                {
                    $this->destFolder = $fullDestPath . '/';
                    $this->destImage = $this->sourceImage;
                }
                else
                {
                    $x = explode('/', $fullDestPath);
                    $this->destImage = end($x);
                    $this->destFolder = str_replace($this->destImage, '', $fullDestPath);
                }
            }
        }
        
        $xp = $this->explodeName($this->destImage);
        
        $filename = $xp['name'];
        $file_ext = $xp['ext'];
        
        $this->fullSrcPath = $this->sourceFolder . $this->sourceImage;
        $this->fullDstPath = $this->destFolder . $filename . $file_ext;
        
        if ($this->createThumb && $this->thumbMarker != '')
        {
            $this->fullThumbPath = $this->destFolder . $filename . $this->thumbMarker . $file_ext;
        }
        
        if ($this->maintainRatio === TRUE && ($this->width != '' and $this->height != ''))
        {
            $this->imageReproportion();
        }
        
        if ($this->width == '')
        {
            $this->width = $this->origWidth;
        }
        
        if ($this->height == '')
        {
            $this->height = $this->origHeight;
        }
        
        $this->quality = trim(str_replace("%", "", $this->quality));
        
        if ($this->quality == '' or $this->quality == 0 or ! is_numeric($this->quality))
        {
            $this->quality = 90;
        }
        
        $this->xAxis = ($this->xAxis == '' or ! is_numeric($this->xAxis)) ? 0 : $this->xAxis;
        $this->yAxis = ($this->yAxis == '' or ! is_numeric($this->yAxis)) ? 0 : $this->yAxis;
        
        if ($this->wmFontColor != '')
        {
            if (strlen($this->wmFontColor) == 6)
            {
                $this->wmFontColor = '#' . $this->wmFontColor;
            }
        }
        
        if ($this->wmShadowColor != '')
        {
            if (strlen($this->wmShadowColor) == 6)
            {
                $this->wmShadowColor = '#' . $this->wmShadowColor;
            }
        }
        
        if ($this->wmOverlayPath != '')
        {
            $this->wmOverlayPath = str_replace("\\", "/", realpath($this->wmOverlayPath));
        }
        
        if ($this->wmShadowColor != '')
        {
            $this->wmUseDropShadow = TRUE;
        }
        
        if ($this->wmFontPath != '')
        {
            $this->wmUseTruetype = TRUE;
        }
        
        return TRUE;
    }

    function resize ()
    {
        $protocol = 'imageProcess' . ucfirst($this->imageLibrary);
        
        if (preg_match('/gd2$/i', $protocol))
        {
            $protocol = 'imageProcessGd';
        }
        
        return $this->$protocol('resize');
    }

    function crop ()
    {
        $protocol = 'imageProcess' . ucfirst($this->imageLibrary);
        
        if (preg_match('/gd2$/i', $protocol))
        {
            $protocol = 'imageProcessGd';
        }
        
        return $this->$protocol('crop');
    }

    function rotate ()
    {
        $degs = array(90, 180, 270, 'vrt', 'hor');
        
        if ($this->rotationAngle == '' or ! in_array($this->rotationAngle, $degs))
        {
            $this->setError('imglib_rotationAngle_required');
            return FALSE;
        }
        
        if ($this->rotationAngle == 90 or $this->rotationAngle == 270)
        {
            $this->width = $this->origHeight;
            $this->height = $this->origWidth;
        }
        else
        {
            $this->width = $this->origWidth;
            $this->height = $this->origHeight;
        }
        
        if ($this->imageLibrary == 'imagemagick' or $this->imageLibrary == 'netpbm')
        {
            $protocol = 'image_process_' . $this->imageLibrary;
            
            return $this->$protocol('rotate');
        }
        
        if ($this->rotationAngle == 'hor' or $this->rotationAngle == 'vrt')
        {
            return $this->imageMirrorGd();
        }
        else
        {
            return $this->image_rotate_gd();
        }
    }

    function imageProcessGd ($action = 'resize')
    {
        $v2Override = FALSE;
        
        if ($this->dynamicOutput === FALSE)
        {
            if ($this->origWidth == $this->width and $this->origHeight == $this->height)
            {
                if ($this->sourceImage != $this->newImage)
                {
                    if (@copy($this->fullSrcPath, $this->fullDstPath))
                    {
                        @chmod($this->fullDstPath, 0664);
                    }
                }
                
                return TRUE;
            }
        }
        
        if ($action == 'crop')
        {
            $this->origWidth = $this->width;
            $this->origHeight = $this->height;
            
            if ($this->gdVersion() !== FALSE)
            {
                $gdVersion = str_replace('0', '', $this->gdVersion());
                $v2Override = ($gdVersion == 2) ? TRUE : FALSE;
            }
        }
        else
        {
            $this->xAxis = 0;
            $this->yAxis = 0;
        }
        
        if (! ($srcImg = $this->imageCreateGd()))
        {
            return FALSE;
        }
        
        if ($this->origWidth > $this->width || $this->origHeight > $this->height)
        {
            if ($this->imageLibrary == 'gd2' and function_exists('imagecreatetruecolor'))
            {
                $create = 'imagecreatetruecolor';
                $copy = 'imagecopyresampled';
            }
            else
            {
                $create = 'imagecreate';
                $copy = 'imagecopyresized';
            }
            
            $dstImg = $create($this->width, $this->height);
            $copy($dstImg, $srcImg, 0, 0, $this->xAxis, $this->yAxis, $this->width, $this->height, $this->origWidth, $this->origHeight);
            
            if ($this->dynamicOutput == TRUE)
            {
                $this->image_display_gd($dstImg);
            }
            else
            {
                if (! $this->imageSaveGd($dstImg))
                {
                    return FALSE;
                }
            }
            
            imagedestroy($dstImg);
            imagedestroy($srcImg);
            
            @chmod($this->fullDstPath, 0664);
        }
        return TRUE;
    }

    function imageProcessImagemagick ($action = 'resize')
    {
        if ($this->libraryPath == '')
        {
            $this->setError('imglib_libpath_invalid');
            return FALSE;
        }
        
        if (! preg_match("/convert$/i", $this->libraryPath))
        {
            $this->libraryPath = rtrim($this->libraryPath, '/') . '/';
            
            $this->libraryPath .= 'convert';
        }
        
        $cmd = $this->libraryPath . " -quality " . $this->quality;
        
        if ($action == 'crop')
        {
            $cmd .= " -crop " . $this->width . "x" . $this->height . "+" . $this->xAxis . "+" . $this->yAxis . " \"$this->fullSrcPath\" \"$this->fullDstPath\" 2>&1";
        }
        elseif ($action == 'rotate')
        {
            switch ($this->rotationAngle)
            {
                case 'hor':
                $angle = '-flop';
                break;
                case 'vrt':
                $angle = '-flip';
                break;
                default:
                $angle = '-rotate ' . $this->rotationAngle;
                break;
            }
            
            $cmd .= " " . $angle . " \"$this->fullSrcPath\" \"$this->fullDstPath\" 2>&1";
        }
        else
        {
            $cmd .= " -resize " . $this->width . "x" . $this->height . " \"$this->fullSrcPath\" \"$this->fullDstPath\" 2>&1";
        }
        
        $retval = 1;
        
        @exec($cmd, $output, $retval);
        
        if ($retval > 0)
        {
            $this->setError('imglib_image_process_failed');
            return FALSE;
        }
        
        @chmod($this->fullDstPath, DIR_WRITE_MODE);
        
        return TRUE;
    }

    function imageProcessNetpbm ($action = 'resize')
    {
        if ($this->libraryPath == '')
        {
            $this->setError('imglib_libpath_invalid');
            return FALSE;
        }
        
        switch ($this->imageType)
        {
            case 1:
            $cmd_in = 'giftopnm';
            $cmd_out = 'ppmtogif';
            break;
            case 2:
            $cmd_in = 'jpegtopnm';
            $cmd_out = 'ppmtojpeg';
            break;
            case 3:
            $cmd_in = 'pngtopnm';
            $cmd_out = 'ppmtopng';
            break;
        }
        
        if ($action == 'crop')
        {
            $cmd_inner = 'pnmcut -left ' . $this->xAxis . ' -top ' . $this->yAxis . ' -width ' . $this->width . ' -height ' . $this->height;
        }
        elseif ($action == 'rotate')
        {
            switch ($this->rotationAngle)
            {
                case 90:
                $angle = 'r270';
                break;
                case 180:
                $angle = 'r180';
                break;
                case 270:
                $angle = 'r90';
                break;
                case 'vrt':
                $angle = 'tb';
                break;
                case 'hor':
                $angle = 'lr';
                break;
            }
            
            $cmd_inner = 'pnmflip -' . $angle . ' ';
        }
        else
        {
            $cmd_inner = 'pnmscale -xysize ' . $this->width . ' ' . $this->height;
        }
        
        $cmd = $this->libraryPath . $cmd_in . ' ' . $this->fullSrcPath . ' | ' . $cmd_inner . ' | ' . $cmd_out . ' > ' . $this->destFolder . 'netpbm.tmp';
        
        $retval = 1;
        
        @exec($cmd, $output, $retval);
        
        if ($retval > 0)
        {
            $this->setError('imglib_image_process_failed');
            return FALSE;
        }
        
        copy($this->destFolder . 'netpbm.tmp', $this->fullDstPath);
        unlink($this->destFolder . 'netpbm.tmp');
        @chmod($this->fullDstPath, DIR_WRITE_MODE);
        
        return TRUE;
    }

    function imageRotateGd ()
    {
        if (! function_exists('imagerotate'))
        {
            $this->setError('imglib_rotate_unsupported');
            return FALSE;
        }
        
        if (! ($srcImg = $this->imageCreateGd()))
        {
            return FALSE;
        }
        
        $white = imagecolorallocate($srcImg, 255, 255, 255);
        
        $dstImg = imagerotate($srcImg, $this->rotationAngle, $white);
        
        if ($this->dynamicOutput == TRUE)
        {
            $this->image_display_gd($dstImg);
        }
        else
        {
            if (! $this->imageSaveGd($dstImg))
            {
                return FALSE;
            }
        }
        
        imagedestroy($dstImg);
        imagedestroy($srcImg);
        
        @chmod($this->fullDstPath, DIR_WRITE_MODE);
        
        return true;
    }

    function imageMirrorGd ()
    {
        if (! $srcImg = $this->imageCreateGd())
        {
            return FALSE;
        }
        
        $width = $this->origWidth;
        $height = $this->origHeight;
        
        if ($this->rotationAngle == 'hor')
        {
            for ($i = 0; $i < $height; $i ++)
            {
                $left = 0;
                $right = $width - 1;
                
                while ($left < $right)
                {
                    $cl = imagecolorat($srcImg, $left, $i);
                    $cr = imagecolorat($srcImg, $right, $i);
                    
                    imagesetpixel($srcImg, $left, $i, $cr);
                    imagesetpixel($srcImg, $right, $i, $cl);
                    
                    $left ++;
                    $right --;
                }
            }
        }
        else
        {
            for ($i = 0; $i < $width; $i ++)
            {
                $top = 0;
                $bot = $height - 1;
                
                while ($top < $bot)
                {
                    $ct = imagecolorat($srcImg, $i, $top);
                    $cb = imagecolorat($srcImg, $i, $bot);
                    
                    imagesetpixel($srcImg, $i, $top, $cb);
                    imagesetpixel($srcImg, $i, $bot, $ct);
                    
                    $top ++;
                    $bot --;
                }
            }
        }
        
        if ($this->dynamicOutput == TRUE)
        {
            $this->image_display_gd($srcImg);
        }
        else
        {
            if (! $this->imageSaveGd($srcImg))
            {
                return FALSE;
            }
        }
        
        imagedestroy($srcImg);
        
        @chmod($this->fullDstPath, DIR_WRITE_MODE);
        
        return TRUE;
    }

    function watermark ()
    {
        if ($this->wmType == 'overlay')
        {
            return $this->overlayWatermark();
        }
        else
        {
            return $this->textWatermark();
        }
    }

    function overlayWatermark ()
    {
        if (! function_exists('imagecolortransparent'))
        {
            $this->setError('imglib_gd_required');
            return FALSE;
        }
        
        $this->getImageProperties();
        
        $props = $this->getImageProperties($this->wmOverlayPath, TRUE);
        $wmImgType = $props['imageType'];
        $wmWidth = $props['width'];
        $wmHeight = $props['height'];
        
        $wm_img = $this->imageCreateGd($this->wmOverlayPath, $wmImgType);
        $srcImg = $this->imageCreateGd($this->fullSrcPath);
        
        $this->wmVrtAlignment = strtoupper(substr($this->wmVrtAlignment, 0, 1));
        $this->wmHorAlignment = strtoupper(substr($this->wmHorAlignment, 0, 1));
        
        if ($this->wmVrtAlignment == 'B')
            $this->wmVrtOffset = $this->wmVrtOffset * - 1;
        
        if ($this->wmHorAlignment == 'R')
            $this->wmHorOffset = $this->wmHorOffset * - 1;
        
        $xAxis = $this->wmHorOffset + $this->wmPadding;
        $yAxis = $this->wmVrtOffset + $this->wmPadding;
        
        switch ($this->wmVrtAlignment)
        {
            case 'T':
            break;
            case 'M':
            $yAxis += ($this->origHeight / 2) - ($wmHeight / 2);
            break;
            case 'B':
            $yAxis += $this->origHeight - $wmHeight;
            break;
        }
        
        switch ($this->wmHorAlignment)
        {
            case 'L':
            break;
            case 'C':
            $xAxis += ($this->origWidth / 2) - ($wmWidth / 2);
            break;
            case 'R':
            $xAxis += $this->origWidth - $wmWidth;
            break;
        }
        
        if ($wmImgType == 3 and function_exists('imagealphablending'))
        {
            @imagealphablending($srcImg, TRUE);
        }
        
        $rgba = imagecolorat($wm_img, $this->wmXTransp, $this->wmYTransp);
        $alpha = ($rgba & 0x7F000000) >> 24;
        
        if ($alpha > 0)
        {
            imagecopy($srcImg, $wm_img, $xAxis, $yAxis, 0, 0, $wmWidth, $wmHeight);
        }
        else
        {
            imagecolortransparent($wm_img, imagecolorat($wm_img, $this->wmXTransp, $this->wmYTransp));
            imagecopymerge($srcImg, $wm_img, $xAxis, $yAxis, 0, 0, $wmWidth, $wmHeight, $this->wmOpacity);
        }
        
        if ($this->dynamicOutput == TRUE)
        {
            $this->image_display_gd($srcImg);
        }
        else
        {
            if (! $this->imageSaveGd($srcImg))
            {
                return FALSE;
            }
        }
        
        imagedestroy($srcImg);
        imagedestroy($wm_img);
        
        return TRUE;
    }

    function textWatermark ()
    {
        if (! ($srcImg = $this->imageCreateGd()))
        {
            return FALSE;
        }
        
        if ($this->wmUseTruetype == TRUE and ! file_exists($this->wmFontPath))
        {
            $this->setError('字体文件不存在');
            return FALSE;
        }
        
        $this->getImageProperties();
        
        $this->wmFontColor = str_replace('#', '', $this->wmFontColor);
        $this->wmShadowColor = str_replace('#', '', $this->wmShadowColor);
        
        $R1 = hexdec(substr($this->wmFontColor, 0, 2));
        $G1 = hexdec(substr($this->wmFontColor, 2, 2));
        $B1 = hexdec(substr($this->wmFontColor, 4, 2));
        
        $R2 = hexdec(substr($this->wmShadowColor, 0, 2));
        $G2 = hexdec(substr($this->wmShadowColor, 2, 2));
        $B2 = hexdec(substr($this->wmShadowColor, 4, 2));
        
        $txtColor = imagecolorclosest($srcImg, $R1, $G1, $B1);
        $drpColor = imagecolorclosest($srcImg, $R2, $G2, $B2);
        
        if ($this->wmVrtAlignment == 'B')
            $this->wmVrtOffset = $this->wmVrtOffset * - 1;
        
        if ($this->wmHorAlignment == 'R')
            $this->wmHorOffset = $this->wmHorOffset * - 1;
        
        if ($this->wmUseTruetype == TRUE)
        {
            if ($this->wmFontSize == '')
                $this->wmFontSize = '17';
            
            $fontwidth = $this->wmFontSize - ($this->wmFontSize / 4);
            $fontheight = $this->wmFontSize;
            $this->wmVrtOffset += $this->wmFontSize;
        }
        else
        {
            $fontwidth = imagefontwidth($this->wmFontSize);
            $fontheight = imagefontheight($this->wmFontSize);
        }
        
        $xAxis = $this->wmHorOffset + $this->wmPadding;
        $yAxis = $this->wmVrtOffset + $this->wmPadding;
        
        if ($this->wmUseDropShadow == FALSE)
            $this->wmShadowDistance = 0;
        
        $this->wmVrtAlignment = strtoupper(substr($this->wmVrtAlignment, 0, 1));
        $this->wmHorAlignment = strtoupper(substr($this->wmHorAlignment, 0, 1));
        
        switch ($this->wmVrtAlignment)
        {
            case "T":
            break;
            case "M":
            $yAxis += ($this->origHeight / 2) + ($fontheight / 2);
            break;
            case "B":
            $yAxis += ($this->origHeight - $fontheight - $this->wmShadowDistance - ($fontheight / 2));
            break;
        }
        
        $x_shad = $xAxis + $this->wmShadowDistance;
        $y_shad = $yAxis + $this->wmShadowDistance;
        
        switch ($this->wmHorAlignment)
        {
            case "L":
            break;
            case "R":
            if ($this->wmUseDropShadow)
                $x_shad += ($this->origWidth - $fontwidth * strlen($this->wmText));
            $xAxis += ($this->origWidth - $fontwidth * strlen($this->wmText));
            break;
            case "C":
            if ($this->wmUseDropShadow)
                $x_shad += floor(($this->origWidth - $fontwidth * strlen($this->wmText)) / 2);
            $xAxis += floor(($this->origWidth - $fontwidth * strlen($this->wmText)) / 2);
            break;
        }
        
        if ($this->wmUseTruetype)
        {
            if ($this->wmUseDropShadow)
                imagettftext($srcImg, $this->wmFontSize, 0, $x_shad, $y_shad, $drpColor, $this->wmFontPath, $this->wmText);
            imagettftext($srcImg, $this->wmFontSize, 0, $xAxis, $yAxis, $txtColor, $this->wmFontPath, $this->wmText);
        }
        else
        {
            if ($this->wmUseDropShadow)
                imagestring($srcImg, $this->wmFontSize, $x_shad, $y_shad, $this->wmText, $drpColor);
            imagestring($srcImg, $this->wmFontSize, $xAxis, $yAxis, $this->wmText, $txtColor);
        }
        
        if ($this->dynamicOutput == TRUE)
        {
            $this->image_display_gd($srcImg);
        }
        else
        {
            $this->imageSaveGd($srcImg);
        }
        
        imagedestroy($srcImg);
        
        return TRUE;
    }

    function imageCreateGd ($path = '', $imageType = '')
    {
        if ($path == '')
            $path = $this->fullSrcPath;
        
        if ($imageType == '')
            $imageType = $this->imageType;
        
        switch ($imageType)
        {
            case 1:
            if (! function_exists('imagecreatefromgif'))
            {
                $this->setError(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
                return FALSE;
            }
            
            return imagecreatefromgif($path);
            break;
            case 2:
            if (! function_exists('imagecreatefromjpeg'))
            {
                $this->setError(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
                return FALSE;
            }
            
            return imagecreatefromjpeg($path);
            break;
            case 3:
            if (! function_exists('imagecreatefrompng'))
            {
                $this->setError(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
                return FALSE;
            }
            
            return imagecreatefrompng($path);
            break;
        
        }
        
        $this->setError(array('imglib_unsupported_imagecreate'));
        return FALSE;
    }

    function imageSaveGd ($resource)
    {
        switch ($this->imageType)
        {
            case 1:
            if (! function_exists('imagegif'))
            {
                $this->setError(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
                return FALSE;
            }
            
            if (! @imagegif($resource, $this->fullDstPath))
            {
                $this->setError('imglib_save_failed');
                return FALSE;
            }
            break;
            case 2:
            if (! function_exists('imagejpeg'))
            {
                $this->setError(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
                return FALSE;
            }
            
            if (phpversion() == '4.4.1')
            {
                @touch($this->fullDstPath); // PHP 4.4.1 bug #35060 - workaround
            }
            
            if (! @imagejpeg($resource, $this->fullDstPath, $this->quality))
            {
                $this->setError('imglib_save_failed');
                return FALSE;
            }
            break;
            case 3:
            if (! function_exists('imagepng'))
            {
                $this->setError(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
                return FALSE;
            }
            
            if (! @imagepng($resource, $this->fullDstPath))
            {
                $this->setError('imglib_save_failed');
                return FALSE;
            }
            break;
            default:
            $this->setError(array('imglib_unsupported_imagecreate'));
            return FALSE;
            break;
        }
        
        return TRUE;
    }

    function image_display_gd ($resource)
    {
        header("Content-Disposition: filename={$this->sourceImage};");
        header("Content-Type: {$this->mimeType}");
        header('Content-Transfer-Encoding: binary');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
        
        switch ($this->imageType)
        {
            case 1:
            imagegif($resource);
            break;
            case 2:
            imagejpeg($resource, '', $this->quality);
            break;
            case 3:
            imagepng($resource);
            break;
            default:
            echo 'Unable to display the image';
            break;
        }
    }

    function imageReproportion ()
    {
        if (! is_numeric($this->width) or ! is_numeric($this->height) or $this->width == 0 or $this->height == 0)
            return;
        
        if (! is_numeric($this->origWidth) or ! is_numeric($this->origHeight) or $this->origWidth == 0 or $this->origHeight == 0)
            return;
        
        $newWidth = ceil($this->origWidth * $this->height / $this->origHeight);
        $newHeight = ceil($this->width * $this->origHeight / $this->origWidth);
        
        $ratio = (($this->origHeight / $this->origWidth) - ($this->height / $this->width));
        
        if ($this->masterDim != 'width' and $this->masterDim != 'height')
        {
            $this->masterDim = ($ratio < 0) ? 'width' : 'height';
        }
        
        if (($this->width != $newWidth) and ($this->height != $newHeight))
        {
            if ($this->masterDim == 'height')
            {
                $this->width = $newWidth;
            }
            else
            {
                $this->height = $newHeight;
            }
        }
    }

    function getImageProperties ($path = '', $return = FALSE)
    {
        if ($path == '')
        {
            $path = $this->fullSrcPath;
        }
        
        if (! file_exists($path))
        {
            $this->setError('图片不存在');
            return FALSE;
        }
        
        $vals = @getimagesize($path);
        
        $types = array(1=>'gif', 2=>'jpeg', 3=>'png');
        
        $mime = (isset($types[$vals['2']])) ? 'image/' . $types[$vals['2']] : 'image/jpg';
        
        if ($return == TRUE)
        {
            $v['width'] = $vals['0'];
            $v['height'] = $vals['1'];
            $v['imageType'] = $vals['2'];
            $v['sizeStr'] = $vals['3'];
            $v['mimeType'] = $mime;
            
            return $v;
        }
        
        $this->origWidth = $vals['0'];
        $this->origHeight = $vals['1'];
        $this->imageType = $vals['2'];
        $this->sizeStr = $vals['3'];
        $this->mimeType = $mime;
        
        return TRUE;
    }

    function sizeCalculator ($vals)
    {
        if (! is_array($vals))
        {
            return;
        }
        
        $allowed = array('newWidth', 'newHeight', 'width', 'height');
        
        foreach ($allowed as $item)
        {
            if (! isset($vals[$item]) or $vals[$item] == '')
                $vals[$item] = 0;
        }
        
        if ($vals['width'] == 0 or $vals['height'] == 0)
        {
            return $vals;
        }
        
        if ($vals['newWidth'] == 0)
        {
            $vals['newWidth'] = ceil($vals['width'] * $vals['newHeight'] / $vals['height']);
        }
        elseif ($vals['newHeight'] == 0)
        {
            $vals['newHeight'] = ceil($vals['newWidth'] * $vals['height'] / $vals['width']);
        }
        
        return $vals;
    }

    function explodeName ($sourceImage)
    {
        $ext = strrchr($sourceImage, '.');
        $name = ($ext === FALSE) ? $sourceImage : substr($sourceImage, 0, - strlen($ext));
        
        return array('ext'=>$ext, 'name'=>$name);
    }

    function gdLoaded ()
    {
        if (! extension_loaded('gd'))
        {
            if (! dl('gd.so'))
            {
                return FALSE;
            }
        }
        
        return TRUE;
    }

    function thumb ()
    {
        $srcFile = $this->fullSrcPath;
        
        $toFile = $this->fullThumbPath;
        
        $targetWidth = $this->thumbWidth;
        
        $targetHeight = $this->thumbHeight;
        
        switch ($this->imageType)
        {
            case 1:
            {
                $img = imagecreatefromgif($srcFile);
                break;
            }
            case 2:
            {
                $img = imagecreatefromjpeg($srcFile);
                break;
            }
            case 3:
            {
                $img = imagecreatefrompng($srcFile);
                break;
            }
            case 6:
            {
                $img = imagecreatefromwbmp($srcFile);
                break;
            }
        }
        
        $width = imagesx($img);
        $height = imagesy($img);
        
        if (! $width || ! $height)
        {
            return false;
        }
        
        $targetRatio = $targetWidth / $targetHeight;
        
        $imgRatio = $width / $height;
        
        if ($targetRatio > $imgRatio)
        {
            $newHeight = $targetHeight;
            $newWidth = $imgRatio * $targetHeight;
        }
        else
        {
            $newHeight = $targetWidth / $imgRatio;
            $newWidth = $targetWidth;
        }
        
        if ($newHeight > $targetHeight)
        {
            $newHeight = $targetHeight;
        }
        if ($newWidth > $targetWidth)
        {
            $newHeight = $targetWidth;
        }
        
        $newImg = imagecreatetruecolor($targetWidth, $targetHeight);
        
        $padColor = str_replace('#', '', $this->thumbPadColor);
        
        $R = hexdec(substr($padColor, 0, 2));
        $G = hexdec(substr($padColor, 2, 2));
        $B = hexdec(substr($padColor, 4, 2));
        
        $color = ImageColorAllocate($newImg, $R, $G, $B);
        
        if (! @imagefilledrectangle($newImg, 0, 0, $targetWidth - 1, $targetHeight - 1, $color))
        {
            return false;
        }
        
        if (! @imagecopyresampled($newImg, $img, ($targetWidth - $newWidth) / 2, ($targetHeight - $newHeight) / 2, 0, 0, $newWidth, $newHeight, $width, $height))
        {
            return false;
        }
        
        switch ($this->imageType)
        {
            case 1:
            {
                imagegif($newImg, $toFile);
                break;
            }
            case 2:
            {
                imagejpeg($newImg, $toFile, 100);
                break;
            }
            case 3:
            {
                imagepng($newImg, $toFile);
                break;
            }
            case 6:
            {
                imagebmp($newImg, $toFile);
                break;
            }
            default:
            {
                return false;
            }
        }
        
        imagedestroy($newImg);
        imagedestroy($img);
        
        return true;
    }

    function gdVersion ()
    {
        if (function_exists('gd_info'))
        {
            $gdVersion = @gd_info();
            $gdVersion = preg_replace("/\D/", "", $gdVersion['GD Version']);
            
            return $gdVersion;
        }
        
        return FALSE;
    }

    function setError ($msg)
    {
        if (is_array($msg))
        {
            foreach ($msg as $val)
            {
                $this->errorMsg .= ' ' . $val;
            }
        }
        else
        {
            $this->errorMsg = $msg;
        }
    }

}
// END ImageLib Class